from typing import Optional, List
from sqlalchemy.orm import Session
from sqlalchemy import or_, func
from fastapi import HTTPException, status

from app.models.unit_view import UnitView
from app.models.schemas import UnitViewCreate, UnitViewUpdate
from app.services.base import BaseService


class UnitViewService(BaseService[UnitView, UnitViewCreate, UnitViewUpdate]):
    """设备视图服务类"""

    def __init__(self):
        super().__init__(UnitView)

    def get_by_sn_code(self, db: Session, sn_code: str) -> Optional[UnitView]:
        """根据SN码获取设备视图"""
        return db.query(UnitView).filter(UnitView.sn_code == sn_code).first()

    def search_units(
        self, db: Session, *, search: str, skip: int = 0, limit: int = 100
    ) -> List[UnitView]:
        """搜索设备视图"""
        search_pattern = f"%{search}%"
        query = (
            db.query(UnitView)
            .filter(UnitView.sn_code.ilike(search_pattern))
            .offset(skip)
            .limit(limit)
        )
        return query.all()

    def count_search_units(self, db: Session, *, search: str) -> int:
        """搜索设备视图总数"""
        search_pattern = f"%{search}%"
        query = db.query(func.count(UnitView.id)).filter(
            UnitView.sn_code.ilike(search_pattern)
        )
        return query.scalar()

    def is_sn_code_taken(self, db: Session, sn_code: str) -> bool:
        """检查SN码是否已被使用"""
        unit = self.get_by_sn_code(db, sn_code)
        return unit is not None

    def create_unit(self, db: Session, *, unit_in: UnitViewCreate) -> UnitView:
        """创建设备视图"""
        # 检查SN码是否已存在
        if self.is_sn_code_taken(db, unit_in.sn_code):
            raise HTTPException(
                status_code=status.HTTP_400_BAD_REQUEST,
                detail="SN码已存在"
            )
        
        unit_data = unit_in.dict()
        db_unit = UnitView(**unit_data)
        db.add(db_unit)
        db.commit()
        db.refresh(db_unit)
        return db_unit

    def update(self, db: Session, *, db_obj: UnitView, obj_in: UnitViewUpdate) -> UnitView:
        """更新设备视图信息（重写基类方法以添加唯一性验证）"""
        # 获取更新数据
        try:
            update_data = obj_in.dict(exclude_unset=True)
        except AttributeError:
            update_data = {k: v for k, v in obj_in.__dict__.items() if v is not None}

        # 移除None值和空字符串
        update_data = {
            k: v for k, v in update_data.items() if v is not None and v != ""
        }

        # 检查SN码唯一性
        if "sn_code" in update_data and update_data["sn_code"]:
            existing_unit = self.get_by_sn_code(db, update_data["sn_code"])
            if existing_unit and existing_unit.id != db_obj.id:
                raise HTTPException(
                    status_code=status.HTTP_400_BAD_REQUEST,
                    detail="SN码已存在"
                )

        # 更新字段
        for field, value in update_data.items():
            if hasattr(db_obj, field):
                setattr(db_obj, field, value)

        db.commit()
        db.refresh(db_obj)
        return db_obj


# 创建全局实例
unit_view_service = UnitViewService()